package fileServiceAndroid;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;

import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

import entities.CSFileWrapper;
import entities.Device;
import entities.DeviceType;

public class FileServiceClient {

	public void sendFile(CSFileWrapper file, String ip) throws UnknownHostException, IOException{
		System.out.println("FileServiceClient: sendFile()");
		SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
		SSLSocket service = (SSLSocket) factory.createSocket(ip, 2081);
		service.setEnabledCipherSuites(service.getSupportedCipherSuites());
		service.startHandshake();
//		Socket service = new Socket(ip, 2081);
		
		OutputStreamWriter osw = new OutputStreamWriter(service.getOutputStream());
		BufferedWriter out = new BufferedWriter(osw);

		InputStreamReader isr = new InputStreamReader(service.getInputStream());
		BufferedReader in = new BufferedReader(isr);

		out.write("sendfile");
		out.write("\n");
		out.flush();
		
		String serviceMessage = in.readLine();
		if(serviceMessage.equalsIgnoreCase("sendfilename")){
			out.write(file.getFileName());
			out.write("\n");
			out.write("startfileservice");
			out.write("\n");
			out.flush();
			
			serviceMessage = in.readLine();
			if(serviceMessage.equalsIgnoreCase("fileservicestarted")){
				serviceMessage = in.readLine();
				if(serviceMessage.equalsIgnoreCase("sendfilesize")){
					out.write(String.valueOf(file.getData().length));
					out.write("\n");
					out.flush();
					
					FileReceiverService fs = new FileReceiverService();
					fs.sendFile(file.getData(), service.getInetAddress());
					
					serviceMessage = in.readLine();
					if(serviceMessage.equalsIgnoreCase("filereceived")){
						
					}else{
						System.out.println("Invalid Message");
						System.out.println(serviceMessage);					
					}
				}else{
					System.out.println("Invalid Message");
					System.out.println(serviceMessage);
				}
			}else{
				System.out.println("Invalid Message");
				System.out.println(serviceMessage);					
			}
		}else{
			System.out.println("Invalid Message");
			System.out.println(serviceMessage);					
		}
		in.close();
		out.close();
		service.close();
	}
	
	public Device getDevice(String ip) throws UnknownHostException, IOException{
		System.out.println("FileServiceClient: getDevice()");
		Device d = new Device();		
		
		SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
		SSLSocket service = (SSLSocket) factory.createSocket(ip, 2081);
		service.setEnabledCipherSuites(service.getSupportedCipherSuites());
		service.startHandshake();
		
		
//		Socket service = new Socket(ip, 2081);
		
		OutputStreamWriter osw = new OutputStreamWriter(service.getOutputStream());
		BufferedWriter out = new BufferedWriter(osw);

		InputStreamReader isr = new InputStreamReader(service.getInputStream());
		BufferedReader in = new BufferedReader(isr);
		
		out.write("getdevice");
		out.write("\n");
		out.flush();
		
		String serviceMessage = in.readLine();
		if(serviceMessage.equalsIgnoreCase("devicestart")){
			String deviceData = in.readLine();
			String[] data = deviceData.split(";");
			for(String s : data){
				String[] params =  s.split(":");
				
				if(params[0].equalsIgnoreCase("Name")){
					d.setDeviceName(params[1]);
				}else if(params[0].equalsIgnoreCase("IP")){
					d.setIpAddress(params[1]);
				}else if(params[0].equalsIgnoreCase("UUID")){
					d.setUUID(params[1]);
				}else if(params[0].equalsIgnoreCase("Type")){
					d.setDeviceType(DeviceType.valueOf(params[1]));
				}
			}
			
			serviceMessage = in.readLine();
			if(serviceMessage.equalsIgnoreCase("arlistart")){
				ArrayList<String> connections = new ArrayList<String>();
				while(!(serviceMessage = in.readLine()).equalsIgnoreCase("arliend")){
					connections.add(serviceMessage);
				}
				d.setConnectedDevices(connections);
			}else{
				System.out.println("Invalid Message");
				System.out.println(serviceMessage);					
			}
			
			serviceMessage = in.readLine();
			if(serviceMessage.equalsIgnoreCase("deviceend")){
				out.write("received");
				out.write("\n");
				out.flush();
			}else{
				System.out.println("Invalid Message");
				System.out.println(serviceMessage);					
			}
		}else{
			System.out.println("Invalid Message");
			System.out.println(serviceMessage);					
		}
		
		out.close();
		in.close();
		service.close();
		return d;
	}
	
	public ArrayList<String> getFileNames(String ip) throws UnknownHostException, IOException{
		System.out.println("FileServiceClient: getFileNames()");
		SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
		SSLSocket service = (SSLSocket) factory.createSocket(ip, 2081);
		service.setEnabledCipherSuites(service.getSupportedCipherSuites());
		service.startHandshake();
//		Socket service = new Socket(ip, 2081);
		
		OutputStreamWriter osw = new OutputStreamWriter(service.getOutputStream());
		BufferedWriter out = new BufferedWriter(osw);

		InputStreamReader isr = new InputStreamReader(service.getInputStream());
		BufferedReader in = new BufferedReader(isr);
		
		out.write("getfilenames");
		out.write("\n");
		out.flush();
		
		String serviceMessage = in.readLine();
		ArrayList<String> fileNames = new ArrayList<String>();
		if(serviceMessage.equalsIgnoreCase("arlistart")){
			while(!(serviceMessage = in.readLine()).equalsIgnoreCase("arliend")){
				fileNames.add(serviceMessage);
			}
		}else{
			System.out.println("Invalid Message");
			System.out.println(serviceMessage);					
		}
		out.write("received");
		out.write("\n");
		out.flush();
		
		out.close();
		in.close();
		service.close();
		
		return fileNames;
	}
	
	public CSFileWrapper getFile(String ip, String fileName) throws UnknownHostException, IOException{
		System.out.println("FileServiceClient: getFile()");
		CSFileWrapper file = new CSFileWrapper();
//		Socket service = new Socket(ip, 2081);
		SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
		SSLSocket service = (SSLSocket) factory.createSocket(ip, 2081);
		service.setEnabledCipherSuites(service.getSupportedCipherSuites());
		service.startHandshake();
		
		OutputStreamWriter osw = new OutputStreamWriter(service.getOutputStream());
		BufferedWriter out = new BufferedWriter(osw);

		InputStreamReader isr = new InputStreamReader(service.getInputStream());
		BufferedReader in = new BufferedReader(isr);
		
		out.write("getfile");
		out.write("\n");
		out.flush();
		
		String serviceMessage = in.readLine();
		if(serviceMessage.equalsIgnoreCase("sendfilename")){
			out.write(fileName);
			out.write("\n");
			out.flush();
			
			serviceMessage = in.readLine();
			if(serviceMessage.equalsIgnoreCase("startfileservice")){
				FileReceiverService fs = new FileReceiverService();
				fs.startReceiveFileService();
				
				out.write("fileservicestarted");
				out.write("\n");
				out.flush();
				
				out.write("sendfilesize");
				out.write("\n");
				out.flush();
				String fileSizeString = in.readLine();
				System.out.println(fileSizeString);
				int fileSize = Integer.parseInt(fileSizeString);
				System.out.println("FSC: afterFileSize");
				
				SSLSocket fservice = fs.receiveFileConnection();
				System.out.println("FSC: afterReceiveFC");
				file = fs.receiveFile(fservice, fileName, fileSize);
				System.out.println("FSC: after receiveFile");
				fs.stopReceiveFileService();
			}else{
				System.out.println("Invalid Message");
				System.out.println(serviceMessage);					
			}
		}else{
			System.out.println("Invalid Message");
			System.out.println(serviceMessage);					
		}
		
		out.close();
		in.close();
		service.close();
		
		return file;
	}	
}
